/*
MIT License

Copyright (c) 2022 МГТУ им. Н.Э. Баумана, кафедра ИУ-6, Михаил Фетисов,

https://bmstu.codes/lsx/simodo/loom
*/

#include "simodo/variable/Variable.h"
#include "simodo/bormental/DrBormental.h"
#include "simodo/inout/format/fmt.h"

#include <cassert>

namespace simodo::variable
{
    Array::Array(const std::vector<Value> & values)
        : _dimensions({static_cast<index_t>(values.size())}), _values(values)
    {}

    Array Array::copy() const
    {
        std::vector<Value> values;

        for(const Value & v : _values)
            values.push_back(v.copy());

        return { _common_type, _dimensions, values };
    }

    const Value & Array::getValueByIndex(const std::vector<index_t> & index) const
    {
        if (_dimensions.size() != index.size())
            throw bormental::DrBormental("Array::getValueByIndex", inout::fmt("Out of indexes count"));

        if (index.size() != 1)
            throw bormental::DrBormental("Array::getValueByIndex", inout::fmt("Unsupported"));

        if (index[0] >= _values.size())
            throw bormental::DrBormental("Array::getValueByIndex", inout::fmt("Out of index"));

        return _values[index[0]];
    }

    VariableRef Array::getRefByIndex(const std::vector<index_t> & index) const
    {
        return VariableRef(getValueByIndex(index));
    }

}